﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using System.IO.Compression;

namespace UtilLib.SQL
{
    class WebRef
    {
        public void DBMCADD(object[] selectzdm, DataSet ds)
        {
            if (ds.Tables.IndexOf("DBMC") == -1)
            {
                DataTable dt1 = DBMC();
                ds.Tables.Add(dt1);
            }
            AddDataTable(ds.Tables["DBMC"], selectzdm);
        }
        /// <summary>
        /// 将object格式化成字节数组byte[]
        /// </summary>
        /// <param name="dsOriginal">object对象</param>
        /// <returns>字节数组</returns>
        public byte[] GetBinaryFormatData(object dsOriginal)
        {
            byte[] binaryDataResult = null;
            MemoryStream memStream = new MemoryStream();
            IFormatter brFormatter = new BinaryFormatter();
            brFormatter.Serialize(memStream, dsOriginal);
            binaryDataResult = memStream.ToArray();
            memStream.Close();
            memStream.Dispose();
            return binaryDataResult;
        }
        public DataTable DBMC()
        {
            DataTable dt1 = new DataTable();
            dt1.TableName = "DBMC";
            dt1.Columns.Add("bid", typeof(string));//bid 即当前操作的别名；
            dt1.Columns.Add("bmc", typeof(string));//表名称
            dt1.Columns.Add("blx", typeof(string));//XTBM为系统表(指查询系统表)，FABM为方案表(指查询方案表)
            dt1.Columns.Add("TableName", typeof(string));//放操作标识 select,update,insert,delete,
            dt1.Columns.Add("on", typeof(object));//内存表名称（只在select使用), #：select(多表)，select设计到多表查询时给select操作赋零时表名，查询零时表select赋'#'号 ；其他操作为空
            dt1.Columns["on"].DefaultValue = "";//默认值=   坐标时：= + -
            return dt1;
        }

        public void insertAdd(string[] zdm, object[] nr, DataSet ds, string bid)
        {
            if (ds.Tables.IndexOf("insert") == -1)
            {
                DataTable dt4 = new DataTable();
                dt4.TableName = "insert";
                dt4.Columns.Add("bid", typeof(string));//插入：bid=1
                dt4.Columns.Add("zdm", typeof(string));
                dt4.Columns.Add("nr", typeof(object));//内容列为obj类型， 方便sql语句对数据类型的转换
                ds.Tables.Add(dt4);
            }

            for (int i = 0; i < zdm.Length; i++)
            {
                AddDataTable(ds.Tables["insert"], new object[] { bid, zdm[i], nr[i] });

            }
        }

        public void selectAdd(string bid, object[] selectzdm, string[] aszdm, DataSet ds)
        {
            if (ds.Tables.IndexOf("select") == -1)
            {
                DataTable dt2 = select();
                ds.Tables.Add(dt2);
            }
            for (int i = 0; i < selectzdm.Length; i++)
            {
                AddDataTable(ds.Tables["select"], new object[] { bid, selectzdm[i], aszdm != null ? aszdm[i] : "" });
            }
        }

        private DataTable select()
        {
            DataTable dt2 = new DataTable();
            dt2.TableName = "select";
            dt2.Columns.Add("bid", typeof(string));//查询：bid=100
            dt2.Columns.Add("zdm", typeof(object));
            dt2.Columns.Add("as", typeof(object));//将传入的字段名命别名
            dt2.Columns["as"].DefaultValue = "";//默认值=   坐标时：= + -
            return dt2;
        }
        public void selectallAdd(object[] selectzdm, string[] aszdm, DataSet ds, string bid)
        {
            if (ds.Tables.IndexOf("selectall") == -1)
            {
                DataTable dt2 = new DataTable();
                dt2.TableName = "selectall";
                dt2.Columns.Add("bid", typeof(string));//查询：bid=100
                dt2.Columns.Add("zdm", typeof(object));
                dt2.Columns.Add("as", typeof(object));//将传入的字段名命别名
                dt2.Columns["as"].DefaultValue = "";//默认值=   坐标时：= + -
                ds.Tables.Add(dt2);
            }
            for (int i = 0; i < selectzdm.Length; i++)
            {
                AddDataTable(ds.Tables["selectall"], new object[] { bid, selectzdm[i], aszdm[i] });
            }
        }
        public void selectNextAdd(object[] selectzdm, DataSet ds, string bid, int xh)
        {
            if (ds.Tables.IndexOf("selectnext") == -1)
            {
                DataTable dt2 = new DataTable();
                dt2.TableName = "selectnext";
                dt2.Columns.Add("bid", typeof(string));//查询：bid=100
                dt2.Columns.Add("zdm", typeof(string));
                dt2.Columns.Add("xh", typeof(int));//序号
                ds.Tables.Add(dt2);
            }
            for (int i = 0; i < selectzdm.Length; i++)
            {
                AddDataTable(ds.Tables["selectnext"], new object[] { bid, selectzdm[i], xh });

            }
        }
        public void whereAdd(object[] wherezdm, DataSet ds)
        {
            if (ds.Tables.IndexOf("where") == -1)
            {
                //查询，修改，删除where条件
                DataTable dt3 = new DataTable();
                dt3.TableName = "where";
                dt3.Columns.Add("bid", typeof(string));//查询：bid=100
                dt3.Columns.Add("zkh", typeof(string));//左括号：(
                dt3.Columns.Add("zdm", typeof(string));//字段名
                //dt3.Columns.Add("type", typeof(string));//字段类型：n:数字；c:字符串；d:日期
                dt3.Columns.Add("djz", typeof(string));//等价值：(大于、大于等于、小于、小于等于、等于、包含)
                dt3.Columns.Add("nr", typeof(object));//查询字段的值
                dt3.Columns.Add("ykh", typeof(string));//右括号：）
                dt3.Columns.Add("gx", typeof(string));//关系：（并且、或者）
                ds.Tables.Add(dt3);
            }
            AddDataTable(ds.Tables["where"], wherezdm);
        }

        public void updateAdd(string bid, string[] zdm, string gx, object[] nr, DataSet ds)
        {
            if (ds.Tables.IndexOf("update") == -1)
            {
                DataTable dt2 = new DataTable();
                dt2.TableName = "update";
                dt2.Columns.Add("bid", typeof(string));
                dt2.Columns.Add("zdm", typeof(string));
                dt2.Columns.Add("gx", typeof(string));
                dt2.Columns["gx"].DefaultValue = "=";//默认值=   坐标时：= + -
                dt2.Columns.Add("nr", typeof(object));
                ds.Tables.Add(dt2);
            }
            for (int i = 0; i < zdm.Length; i++)
            {
                AddDataTable(ds.Tables["update"], new object[] { bid, zdm[i], gx, nr[i] });
            }
        }

        /// <summary>
        /// 给dt中灌值
        /// </summary>
        /// <param name="dt">要添加数据的DataTable</param>
        /// <param name="bl">存放字段或内容的数组object</param>
        /// <returns></returns>
        public bool AddDataTable(DataTable dt, object[] bl)
        {
            DataRow dr1 = dt.NewRow();

            if (bl.Length == dr1.ItemArray.Length)//bl的长度和dt中行的列数相等 才循环给dr中加bl的值，然后在添加到dt中
            {
                for (int i = 0; i < bl.Length; i++)
                {
                    dr1[i] = bl[i];
                }
                dt.Rows.Add(dr1);
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 解析WEB响应的列,配合SlectedsToDataSet（）方法，生成DataSet结构
        /// </summary>
        /// <param name="cs">web端返回的WebSlected[]类数组</param>
        /// <param name="k">第几个WebSlected[]数组</param>
        /// <param name="ds">要返回的DataSet</param>
        private static void dtColumnAdd(UtilLib.WebReference.WebSlected[] cs, int k, DataSet ds)
        {
            DataTable dt = new DataTable();
            dt.TableName = cs[k].bmc;
            ds.Tables.Add(dt);
            for (int i = k; i < cs.Length; i++)
            {
                if (cs[k].bmc == cs[i].bmc && ds.Tables[cs[i].bmc].Columns.IndexOf(cs[i].zdm) == -1)
                {
                    ds.Tables[cs[i].bmc].Columns.Add(cs[i].zdm, typeof(object));
                }
                else
                {
                    break;
                }
            }
        }

        /// <summary>
        /// 将序列化后的byte[]，反序列化成object
        /// </summary>
        /// <param name="binaryData"></param>
        /// <returns></returns>
        public object RetrieveObject(byte[] binaryData)
        {
            MemoryStream memStream = new MemoryStream(binaryData);
            IFormatter brFormatter = new BinaryFormatter();
            Object obj = brFormatter.Deserialize(memStream);
            return obj;
        }
        ///// <summary>
        ///// 将object格式化成字节数组byte[]
        ///// </summary>
        ///// <param name="dsOriginal">object对象</param>
        ///// <returns>字节数组</returns>
        //public byte[] GetBinaryFormatData(object dsOriginal)
        //{
        //    byte[] binaryDataResult = null;
        //    MemoryStream memStream = new MemoryStream();
        //    IFormatter brFormatter = new BinaryFormatter();
        //    brFormatter.Serialize(memStream, dsOriginal);
        //    binaryDataResult = memStream.ToArray();
        //    memStream.Close();
        //    memStream.Dispose();
        //    return binaryDataResult;
        //}

        public string ConvertToString(byte[] thebyte)
        {
            char[] Chars = new char[System.Text.Encoding.Default.GetCharCount(thebyte, 0, thebyte.Length)];
            System.Text.Encoding.Default.GetChars(thebyte, 0, thebyte.Length, Chars, 0);
            string newString = new string(Chars);
            return newString;
        }

        /// <summary>
        /// 解析WEB响应生成DataSet结构
        /// </summary>
        /// <param name="cs">WEB响应</param>
        /// <returns>DataSet</returns>
        public DataSet SlectedsToDataSet(UtilLib.WebReference.WebSlected[] cs)
        {
            DataSet ds = new DataSet();
            DataRow dr = null;
            string bmc = "";
            for (int i = 0; i < cs.Length; i++)
            {
                if (bmc != cs[i].bmc)
                {
                    bmc = cs[i].bmc;
                    dtColumnAdd(cs, i, ds);

                }
                if (cs[i].zdm == ds.Tables[cs[i].bmc].Columns[0].ColumnName)
                {
                    dr = ds.Tables[cs[i].bmc].NewRow();
                    ds.Tables[cs[i].bmc].Rows.Add(dr);
                }
                dr[cs[i].zdm] = cs[i].nr;
            }
            return ds;
        }




        /// <summary>
        /// 解析封装WEB可识别的请求
        /// </summary>
        /// <param name="ds">客户请求</param>
        /// <returns>WebSlected[]</returns>
        public UtilLib.WebReference.WebSlected[] DataSetToSlecteds(DataSet ds)
        {
            int x = 0;
            for (int i = 0; i < ds.Tables.Count; i++)
            {
                x += ds.Tables[i].Columns.Count * ds.Tables[i].Rows.Count;
            }
            WebReference.WebSlected[] sd = new WebReference.WebSlected[x];
            x = 0;
            for (int i = 0; i < ds.Tables.Count; i++)
            {
                for (int j = 0; j < ds.Tables[i].Rows.Count; j++)
                {
                    for (int k = 0; k < ds.Tables[i].Columns.Count; k++)
                    {
                        WebReference.WebSlected s = new WebReference.WebSlected();
                        s.bmc = ds.Tables[i].TableName;
                        s.zdm = ds.Tables[i].Columns[k].ColumnName;
                        s.nr = ds.Tables[i].Rows[j][k];//字段内容
                        sd[x] = s;
                        x++;
                    }
                }
            }
            return sd;
        }

        /// <summary>
        /// 项目所在目录
        /// </summary>
        /// <returns></returns>
        public string GetPath()
        {
            return Application.StartupPath;
        }

        /// <summary>
        /// 格式化当前时间: 
        /// 1:yyMMddHHmmss; 2:yyyy-MM\dd\
        /// </summary>
        /// <returns></returns>
        public string FormatNowTime(int num)
        {
            if (num == 1)
            {
                return DateTime.Now.ToString("yyMMddHHmmss");
            }
            else if (num == 2)
            {
                return DateTime.Now.ToString("yyyy-MM") + @"\" + DateTime.Now.Day;
            }
            return "";
        }


        /// <summary>
        /// 二进制数据转换为word文件
        /// </summary>
        /// <param name="data">二进制数据</param>
        /// <param name="fileName">word文件名</param>
        /// <returns>word保存的相对路径</returns>
        public string ByteConvertWord(byte[] data, string fileName)
        {
            string savePath = @"\SystemWord\" + FormatNowTime(2) + @"\";


            if (!System.IO.Directory.Exists(GetPath() + savePath))
            {
                Directory.CreateDirectory(GetPath() + savePath);
            }
            savePath += fileName + ".doc";
            string filePath = GetPath() + savePath;


            FileStream fs;
            if (System.IO.File.Exists(filePath))
            {
                fs = new FileStream(filePath, FileMode.Truncate);
            }
            else
            {
                fs = new FileStream(filePath, FileMode.CreateNew);
            }
            BinaryWriter br = new BinaryWriter(fs);
            br.Write(data, 0, data.Length);
            br.Close();
            fs.Close();
            return savePath;
        }

        public byte[] GetBinaryFormatDataSetCompress(DataSet dsOriginal)
        {
            byte[] binaryDataResult = null;
            MemoryStream memStream = new MemoryStream();
            IFormatter brFormatter = new BinaryFormatter();
            dsOriginal.RemotingFormat = SerializationFormat.Binary;
            brFormatter.Serialize(memStream, dsOriginal);
            binaryDataResult = memStream.ToArray();
            memStream.Close();
            memStream.Dispose();
            return Compress(binaryDataResult);
        }
        /// <summary>
        /// 将字节数组反序列化成DataSet对象
        /// </summary>
        /// <param name="binaryData">字节数组</param>
        /// <returns>DataSet对象</returns>
        public DataSet RetrieveDataSet(byte[] binaryData)
        {
            DataSet dsOriginal = new DataSet();
            try
            {
                MemoryStream memStream = new MemoryStream(binaryData);
                IFormatter brFormatter = new BinaryFormatter();
                Object obj = brFormatter.Deserialize(memStream);
                dsOriginal = (DataSet)obj;
            }
            catch
            {
            }
            return dsOriginal;
        }
        /// <summary>
        /// 解压数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] Decompress(byte[] data)
        {
            if (data == null)
            {
                return new byte[0];
            }

            byte[] bData = new byte[0];
            MemoryStream ms = new MemoryStream();
            GZipStream stream = null;
            MemoryStream temp = new MemoryStream();
            try
            {

                ms.Write(data, 0, data.Length);
                ms.Position = 0;
                stream = new GZipStream(ms, CompressionMode.Decompress, true);
                byte[] buffer = new byte[1024];
                int read = stream.Read(buffer, 0, buffer.Length);
                while (read > 0)
                {
                    temp.Write(buffer, 0, read);
                    read = stream.Read(buffer, 0, buffer.Length);
                }
                //必须把stream流关闭才能返回ms流数据,不然数据会不完整
                stream.Close();
                stream.Dispose();
                ms.Close();
                ms.Dispose();
                bData = temp.ToArray();
                temp.Close();
                temp.Dispose();
            }

            catch
            {
                if (stream != null)
                {
                    stream.Close();
                    temp.Dispose();
                }
                ms.Close();
                ms.Dispose();
                temp.Close();
                temp.Dispose();

            }
            return bData;
        }

        /// <summary>
        /// 压缩数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] Compress(byte[] data)
        {
            if (data == null)
            {
                return null;
            }
            byte[] bData;
            MemoryStream ms = new MemoryStream();
            GZipStream stream = new GZipStream(ms, CompressionMode.Compress, true);
            try
            {
                stream.Write(data, 0, data.Length);
            }
            catch { }
            stream.Close();
            stream.Dispose();
            //必须把stream流关闭才能返回ms流数据,不然数据会不完整
            //并且解压缩方法stream.Read(buffer, 0, buffer.Length)时会返回0
            bData = ms.ToArray();
            ms.Close();
            ms.Dispose();
            return bData;
        }

    }
}
